package com.demo.androidgame.finsternis;

import java.util.List;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;

import com.demo.androidgame.fx.Game;
import com.demo.androidgame.fx.Input.KeyEvent;
import com.demo.androidgame.fx.Input.TouchEvent;
import com.demo.androidgame.fx.gl.Camera2D;
import com.demo.androidgame.fx.gl.FPSCounter;
import com.demo.androidgame.fx.gl.SpriteBatcher;
import com.demo.androidgame.fx.gl.TextureRegion;
import com.demo.androidgame.fx.impl.GLScreen;
import com.demo.androidgame.fx.math.OverlapTester;
import com.demo.androidgame.fx.math.Rectangle;
import com.demo.androidgame.fx.math.Vector2;
import com.demo.androidgame.finsternis.World.WorldListener;
import com.demo.androidgame.finsternis.Settings;
import com.demo.androidgame.finsternis.World;

public class GameScreen extends GLScreen {
    static final int GAME_READY = 0;    
    static final int GAME_RUNNING = 1;
    static final int GAME_PAUSED = 2;
    static final int GAME_STAGE_CLEAR = 3;
    static final int GAME_OVER = 4;
    
    
    static boolean getJump = false;
    
    int state;
    Camera2D guiCam;
    Vector2 touchPoint;
    SpriteBatcher batcher;    
    World world;
    WorldListener worldListener;
    WorldRenderer renderer;    
    Rectangle pauseBounds;
    Rectangle resumeBounds;
    Rectangle restartBounds;
    Rectangle mainmenuBounds;
    Rectangle stageselectBounds;
    boolean nextStageActive = true;
    FPSCounter fpsCounter;
    
    TextureRegion[] timer_one = {
    		Assets.zero, Assets.one, Assets.two, Assets.three, Assets.four, 
    		Assets.five, Assets.six, Assets.seven, Assets.eight, Assets.nine };
    TextureRegion[] timer_two = {
    		Assets.zero_r, Assets.one_r, Assets.two_r, Assets.three_r, Assets.four_r, 
    		Assets.five_r, Assets.six_r, Assets.seven_r, Assets.eight_r, Assets.nine_r };
    
    public static float bobStartX, bobStartY;
    
    public GameScreen(Game game) {
        super(game);
        state = GAME_READY;
        guiCam = new Camera2D(glGraphics, 480, 320);
        touchPoint = new Vector2();
        batcher = new SpriteBatcher(glGraphics, 1000);
        worldListener = new WorldListener() {
            @Override
            public void jump() {            
                Assets.playSound(Assets.jumpSound);
            }

            @Override
            public void highJump() {
            }

            @Override
            public void hit() {
            }

            @Override
            public void coin() {
            }                      
        };
        world = new World(worldListener, game);
        renderer = new WorldRenderer(glGraphics, batcher, world);
        pauseBounds = new Rectangle(470- 50, 310- 50, 50, 50); //470 - 10, 310 - 7, 20, 15
        resumeBounds = new Rectangle(240 - 64, 250-20, 128, 40); //240, 250, 128, 40
        restartBounds = new Rectangle(240 - 73,  200-20, 146, 40); //240, 200, 146, 40
        mainmenuBounds = new Rectangle(240 - 89,  150-20, 178, 40); //240, 150, 178, 40
        stageselectBounds = new Rectangle(240 - 100,  100-20, 200, 40); //240, 100, 200, 40
        fpsCounter = new FPSCounter();
        
    }

	@Override
	public void update(float deltaTime) {
		//backButton
		List<KeyEvent> keyEvents = game.getInput().getKeyEvents();
        int key = keyEvents.size();
        for (int i = 0; i <key; i++) {
        	KeyEvent event2 = keyEvents.get(i);
        	if (event2.type == KeyEvent.KEY_DOWN){	
	        	if (event2.keyCode == android.view.KeyEvent.KEYCODE_BACK) {
	        		((Activity)game).runOnUiThread(new Runnable() {
						@Override
						public void run() {
							new AlertDialog.Builder((Activity)game)
		        			.setIcon(R.drawable.finsternis)
		        			.setTitle("Finsternis")
		        			.setMessage("게임을 종료하시겠습니까?")
		        			.setCancelable(true)
		        			.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									((Activity)game).finish();
								}
		        			}).setNegativeButton("No", null).show();
						}
					});
	        	} else if (event2.keyCode == android.view.KeyEvent.KEYCODE_MENU) {
	        		((Activity)game).runOnUiThread(new Runnable() {
						@Override
						public void run() {
							pause();
						}
					});
	        	}
        	}
        }
		
		
		
		
	    if(deltaTime > 0.1f)
	        deltaTime = 0.1f;
	    
	    switch(state) {
	    case GAME_READY:
	        updateReady();
	        break;
	    case GAME_RUNNING:
	        updateRunning(deltaTime);
	        break;
	    case GAME_PAUSED:
	        updatePaused();
	        break;
	    case GAME_STAGE_CLEAR:
	        updateClear();
	        break;
	    case GAME_OVER:
	        updateGameOver();
	        break;
	    }
	    
	    if (Settings.soundEnabled) {
	    	Assets.mainMusic.pause();
	    	Assets.gameMusic.play();
	    } else {
	    	Assets.mainMusic.pause();
	    	Assets.gameMusic.pause();
	    }
	}
	
	private void updateReady() {
	    if(game.getInput().getTouchEvents().size() > 0) {
	        state = GAME_RUNNING;
	    }
	}
	
	private void updateRunning(float deltaTime) {

		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
	    int len = touchEvents.size();
	    for(int i = 0; i < len; i++) {                   
	        TouchEvent event = touchEvents.get(i);
	        if(event.type != TouchEvent.TOUCH_DOWN)
	            continue;
	         
	        touchPoint.set(event.x, event.y);
	        guiCam.touchToWorld(touchPoint);
	        
	        if(OverlapTester.pointInRectangle(pauseBounds, touchPoint)) {
	            Assets.playSound(Assets.clickSound);
	            state = GAME_PAUSED;
	            return;
	        }
	        getJump = true;	   
	    }
	    world.update(deltaTime, game.getInput().getAccelX());		//getAccelX : 중력가속도 센서의 값

	    if(world.state == World.WORLD_STATE_NEXT_LEVEL) {			//스테이지 다음 레벨 상태로 가면
	        state = GAME_STAGE_CLEAR;        						//게임 스크린 상태도 바꿔줌
	        nextStageActive = true;
	        if ( state == GAME_STAGE_CLEAR ) {
	        	Settings.stageActiveChange(nextStageActive);
	        	Settings.save(game.getFileIO());
	        }
	    }
	    if(world.state == World.WORLD_STATE_GAME_OVER) {
	        state = GAME_OVER;
	    }
	}
	
	private void updatePaused() {
	    List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
	    int len = touchEvents.size();
	    for(int i = 0; i < len; i++) {
	        TouchEvent event = touchEvents.get(i);
	        
	        touchPoint.set(event.x, event.y);
	        guiCam.touchToWorld(touchPoint);
	        
	        if(OverlapTester.pointInRectangle(resumeBounds, touchPoint)) {
	            Assets.playSound(Assets.clickSound);
	            state = GAME_RUNNING;
	            return;
	        }
	        
	        if(OverlapTester.pointInRectangle(restartBounds, touchPoint)) {
	            Assets.playSound(Assets.clickSound);
	            game.setScreen(new GameScreen(game));
	            state = GAME_READY;
	            
	            return;
	        
	        }
	        
	        if(OverlapTester.pointInRectangle(mainmenuBounds, touchPoint)) {
	            Assets.playSound(Assets.clickSound);
	            game.setScreen(new MainMenuScreen(game));
	            return;
	        
	        }
	        
	        if(OverlapTester.pointInRectangle(stageselectBounds, touchPoint)) {
	            Assets.playSound(Assets.clickSound);
	            game.setScreen(new StageScreen(game));
	            return;
	        
	        }
	    }
	}
	
	private void updateClear() {
	    List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
	    int len = touchEvents.size();
	    for(int i = 0; i < len; i++) {                   
	        TouchEvent event = touchEvents.get(i);
	        if(event.type != TouchEvent.TOUCH_UP)
	            continue;
	        game.setScreen(new StageScreen(game));
	        world = new World(worldListener, game);
	        renderer = new WorldRenderer(glGraphics, batcher, world);
	        state = GAME_READY;
	        
	    }
	}
	
	private void updateGameOver() {
	    List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
	    int len = touchEvents.size();
	    for(int i = 0; i < len; i++) {                   
	        TouchEvent event = touchEvents.get(i);
	        if(event.type != TouchEvent.TOUCH_UP)
	            continue;
	        game.setScreen(new MainMenuScreen(game));
	    }
	}

	@Override
	public void present(float deltaTime) {
	    GL10 gl = glGraphics.getGL();
	    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
	    gl.glEnable(GL10.GL_TEXTURE_2D);
	    
	    renderer.render();
	    
	    guiCam.setViewportAndMatrices();
	    gl.glEnable(GL10.GL_BLEND);
	    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
	    batcher.beginBatch(Assets.gamefont);
	    switch(state) {
	    case GAME_READY:
	        presentReady();
	        break;
	    case GAME_RUNNING:
	        presentRunning();
	        break;
	    case GAME_PAUSED:
	        presentPaused();
	        break;
	    case GAME_STAGE_CLEAR:
	        presentClear();
	        break;
	    case GAME_OVER:
	        presentGameOver();
	        break;
	    }
	    batcher.endBatch();

	    gl.glDisable(GL10.GL_BLEND);
	    fpsCounter.logFrame();
	}
	
	private void presentReady() {
	    batcher.drawSprite(240, 160, 182, 40, Assets.ready);
	}
	
	private void presentRunning() {
	    batcher.drawSprite(470 - 10, 310 - 7, 20, 15, Assets.pause);
	    
	    int i = (int)world.time / 10;
	    if (i > 2) {
	    	batcher.drawSprite(240-10, 320-15, 20, 27, timer_one[i]);
		    int j = (int)world.time % 10;
		    batcher.drawSprite(240+10, 320-15, 20, 27, timer_one[j]);
	    } else {
	    	batcher.drawSprite(240-10, 320-15, 20, 27, timer_two[i]);
		    int j = (int)world.time % 10;
		    batcher.drawSprite(240+10, 320-15, 20, 27, timer_two[j]);
	    }
	    
	    
	}
	
	private void presentPaused() {     
	    batcher.drawSprite(240, 250, 128, 40, Assets.resume);
	    batcher.drawSprite(240, 200, 146, 40, Assets.reStart);
	    batcher.drawSprite(240, 150, 178, 40, Assets.mainMenu);
	    batcher.drawSprite(240, 100, 200, 40, Assets.stageSelect);
	}
	
	//game clear
	private void presentClear() {
		batcher.drawSprite(240, 150, 215, 40, Assets.clear);
	}
	
	private void presentGameOver() {
	    batcher.drawSprite(240, 160, 310, 40, Assets.gameOver);  
	}

    @Override
    public void pause() {
        if(state == GAME_RUNNING)
            state = GAME_PAUSED;
    }

    @Override
    public void resume() {  
    }

    @Override
    public void dispose() {       
    }
}
